/***************************************************************
|	File:		BitmapFont.cpp
|	Author:		David Stout
|	Course:		SGD 1402
|	Purpose:	BitmapFont class draws text using an image
|				of fixed-size character glyphs
***************************************************************/

#include "BitmapFont.h"
#include "..\TinyXML\tinyxml.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include <ctype.h>
#include <cassert>


/**************************************************************/
// Initialize
//	- configure the font for "SGD_Font_Glow.png"
//	- probably should have parameters / config file
void BitmapFont::Initialize( void )
{
	// Load the image
	/*m_hImage = SGD::GraphicsManager::GetInstance()->LoadTexture(
				L"resource/graphics/SGD_Font_Glow.png" );*/

	/*m_hImage = SGD::GraphicsManager::GetInstance()->LoadTexture(
		L"resource/Fonts/copper_plumbing_bmpFont.png");*/
	m_hImage = SGD::GraphicsManager::GetInstance()->LoadTexture(
		L"resource/Fonts/font1.png");

	TiXmlDocument Rects("resource/Fonts/newfont.xml");
	
	if (Rects.LoadFile())
	{

		TiXmlHandle docHandle(&Rects);
		TiXmlHandle rootHandle(0);

		//Access the root element
		TiXmlElement* element;
		element = Rects.RootElement();

		if (element == nullptr)
			return;

		TiXmlElement * Child;
		Child = element->FirstChildElement();
		while (Child != nullptr)
		{
			SGD::Rectangle temp;
			temp.left = static_cast<float>(atof(Child->Attribute("x")));
			temp.top = static_cast<float>(atof(Child->Attribute("y")));
			int width = atoi(Child->Attribute("width"));
			int height = atoi(Child->Attribute("height"));
			temp.bottom = temp.top + height;
			temp.right = temp.left + width;

			RenderRects.push_back(temp);


			Child = Child->NextSiblingElement();
		}
		
		





	}

	m_nCharWidth		= 60;		//half height = 16 //I-L width = 6, i height = 26
	m_nCharHeight		= 64;
	m_nNumRows			= 10; //5
	m_nNumCols			= 10; //15
	
	m_cFirstChar		= ' ';		// A
	m_bOnlyUppercase	= false;		//false
}


/**************************************************************/
// Terminate
//	- clean up resources
void BitmapFont::Terminate( void )
{
	// Unload the image
	SGD::GraphicsManager::GetInstance()->UnloadTexture( m_hImage );
}


/**************************************************************/
// Draw
//	- draw the text one character at a time,
//	  using the Cell Algorithm to calculate the source rect
void BitmapFont::Draw( const char* output, int x, int y,
			float scale, SGD::Color color ) const
{
	// Validate the image
	assert( m_hImage != SGD::INVALID_HANDLE 
			&& "BitmapFont::Draw - image was not loaded" );

	// Validate the parameter
	assert( output != nullptr 
			&& "BitmapFont::Draw - string cannot be null" );


	// Store the starting X position for newlines
	int colX = x;

	// Iterate through the characters in the string
	for( int i = 0; output[ i ]; i++ )
	{
		// Get the current character
		char ch = output[ i ];
		bool lc = false;

		// Check for whitespace
		if( ch == ' ' )
		{
			// Move to the next position
			x += (int)(60*scale);
			continue;
		}
		else if( ch == '\n' )
		{
			// Move to the next row
			y += (int)(64 * scale);
			x =  colX;
			continue;
		}
		else if( ch == '\t' )
		{
			// Calculate the number of pixels from the start
			int pixels = x - colX;

			// Calculate the number of characters from the start
			int diff = pixels / (int)(60 * scale);

			// Calculate the number of characters to add
			// to get a 4-space alignment
			int spaces = 4 - (diff%4);

			
			// Move to the next position
			x += spaces * (int)(60 * scale);
			continue;
		}

		SGD::Rectangle cell;
		switch (ch)
		{
		case '!':
			cell = RenderRects[1];
			break;
		case '"':
			cell = RenderRects[2];
			break;
		case '#':
			cell = RenderRects[3];
			break;
		case '$':
			cell = RenderRects[4];
			break;
		case '%':
			cell = RenderRects[5];
			break;
		case '&':
			cell = RenderRects[6];
			break;
		case '\'':
			cell = RenderRects[7];
			break;
		case '(':
			cell = RenderRects[8];
			break;
		case ')':
			cell = RenderRects[9];
			break;
		case '*':
			cell = RenderRects[10];
			break;
		case '+':
			cell = RenderRects[11];
			break;
		case ',':
			cell = RenderRects[12];
			break;
		case '-':
			cell = RenderRects[13];
			break;
		case '.':
			cell = RenderRects[14];
			break;
		case '/':
			cell = RenderRects[15];
			break;
		case '0':
			cell = RenderRects[16];
			break;
		case '1':
			cell = RenderRects[17];
			break;
		case '2':
			cell = RenderRects[18];
			break;
		case '3':
			cell = RenderRects[19];
			break;
		case '4':
			cell = RenderRects[20];
			break;
		case '5':
			cell = RenderRects[21];
			break;
		case '6':
			cell = RenderRects[22];
			break;
		case '7':
			cell = RenderRects[23];
			break;
		case '8':
			cell = RenderRects[24];
			break;
		case '9':
			cell = RenderRects[25];
			break;
		case ':':
			cell = RenderRects[26];
			lc = true;
			break;
		case ';':
			cell = RenderRects[27];
			break;
		case '<':
			cell = RenderRects[28];
			lc = true;
			break;
		case '=':
			cell = RenderRects[29];
			break;
		case '>':
			cell = RenderRects[30];
			break;
		case '?':
			cell = RenderRects[31];
			break;
		case '@':
			cell = RenderRects[32];
			lc = true;
			break;
		case 'A':
			cell = RenderRects[33];
			break;
		case 'B':
			cell = RenderRects[34];
			lc = true;
			break;
		case 'C':
			cell = RenderRects[35];
			break;
		case 'D':
			cell = RenderRects[36];
			break;
		case 'E':
			cell = RenderRects[37];
			break;
		case 'F':
			cell = RenderRects[38];
			break;
		case 'G':
			cell = RenderRects[39];
			break;
		case 'H':
			cell = RenderRects[40];
			break;
		case 'I':
			cell = RenderRects[41];
			break;
		case 'J':
			cell = RenderRects[42];
			break;
		case 'K':
			cell = RenderRects[43];
			break;
		case 'L':
			cell = RenderRects[44];
			break;
		case 'M':
			cell = RenderRects[45];
			break;
		case 'N':
			cell = RenderRects[46];
			break;
		case 'O':
			cell = RenderRects[47];
			break;
		case 'P':
			cell = RenderRects[48];
			break;
		case 'Q':
			cell = RenderRects[49];
			break;
		case 'R':
			cell = RenderRects[50];
			break;
		case 'S':
			cell = RenderRects[51];
			break;
		case 'T':
			cell = RenderRects[52];
			break;
		case 'U':
			cell = RenderRects[53];
			break;
		case 'V':
			cell = RenderRects[54];
			break;
		case 'W':
			cell = RenderRects[55];
			break;
		case 'X':
			cell = RenderRects[56];
			break;
		case 'Y':
			cell = RenderRects[57];
			break;
		case 'Z':
			cell = RenderRects[58];
			break;
		case '[':
			cell = RenderRects[59];
			break;
		case '\\':
			cell = RenderRects[60];
			break;
		case ']':
			cell = RenderRects[61];
			break;
		case '^':
			cell = RenderRects[62];
			break;
		case '_':
			cell = RenderRects[63];
			break;
		case '`':
			cell = RenderRects[64];
			break;
		case 'a':
			cell = RenderRects[65];
			break;
		case 'b':
			cell = RenderRects[66];
			break;
		case 'c':
			cell = RenderRects[67];
			break;
		case 'd':
			cell = RenderRects[68];
			break;
		case 'e':
			cell = RenderRects[69];
			break;
		case 'f':
			cell = RenderRects[70];
			break;
		case 'g':
			cell = RenderRects[71];
			break;
		case 'h':
			cell = RenderRects[72];
			break;
		case 'i':
			cell = RenderRects[73];
			break;
		case 'j':
			cell = RenderRects[74];
			break;
		case 'k':
			cell = RenderRects[75];
			break;
		case 'l':
			cell = RenderRects[76];
			break;
		case 'm':
			cell = RenderRects[77];
			break;
		case 'n':
			cell = RenderRects[78];
			break;
		case 'o':
			cell = RenderRects[79];
			break;
		case 'p':
			cell = RenderRects[80];
			break;
		case 'q':
			cell = RenderRects[81];
			break;
		case 'r':
			cell = RenderRects[82];
			break;
		case 's':
			cell = RenderRects[83];
			break;
		case 't':
			cell = RenderRects[84];
			break;
		case 'u':
			cell = RenderRects[85];
			break;
		case 'v':
			cell = RenderRects[86];
			break;
		case 'w':
			cell = RenderRects[87];
			break;
		case 'x':
			cell = RenderRects[88];
			break;
		case 'y':
			cell = RenderRects[89];
			break;
		case 'z':
			cell = RenderRects[90];
			break;
		case '{':
			cell = RenderRects[91];
			break;
		case '|':
			cell = RenderRects[92];
			break;
		case '}':
			cell = RenderRects[93];
			break;
		case '~':
			cell = RenderRects[94];
			break;
		default:
			break;
		}


	

		// Draw the character
		
			SGD::GraphicsManager::GetInstance()->DrawTextureSection(
			m_hImage, { (float)x, (float)y},
			cell, 0.0f, {},
			color, { scale, scale });
		
		// Move to the next position
			if (ch == 'G' || ch == 'O' || ch == 'C' || ch == 'e')
			{
				x += (int)(35 * scale);
			}
			else
			x += (int)(30 * scale);
	}
}
